import datetime
import hashlib
import hmac
import random
import time
    
from django.conf import settings
from django.db import models

from Action import Action
from Channel import Channel
from PrivateChannel import PrivateChannel

#Python 2.4 compatibility
sha256 = hashlib.sha256
try:
    getattr(sha256, 'new')
except AttributeError:
    from HashlibProxy import HashlibProxy
    sha256 = HashlibProxy(hashlib.sha256)
    
class User(models.Model):
    class Meta:
        app_label = 'chat'

    STATUSES = (
        (u'ONLINE', u'Online'),
        (u'AWAY', u'Away'),
        (u'EXAWAY', u'Extended Away'),
    )

    timestamp = models.DateTimeField(auto_now=True)
    username = models.CharField(max_length=255, unique=True)
    identity_id = models.CharField(max_length=64, unique=True)
    identity_key = models.CharField(max_length=512)

    channels = models.ManyToManyField(Channel)
    status = models.CharField(max_length=32, choices=STATUSES, default=u'ONLINE')
    
    @classmethod    
    def verify_message(cls, user_id, message_key, message_hash):
        try:
            user = User.objects.get(identity_id=user_id)
            user.save()
            if(message_hash == hmac.new(str(user.identity_key), message_key, sha256).hexdigest()):
                return user
        except User.DoesNotExist:
            return None
        return None
    
    @classmethod    
    def verify_target(cls, user, target):
        channel = None
        try:
            channel = Channel.objects.get(hash=target)
        except Channel.DoesNotExist:
            pass
        
        if (channel is not None) and (channel in user.channels.all()):
            return channel

        return None

    @classmethod
    def prune_users(cls):
        for user in User.objects.filter(timestamp__lt=datetime.datetime.fromtimestamp(time.time() - settings.PCDM_CHAT_IDLE_TIME_IN_SECONDS)).all():
            for channel in user.channels.all():
                action = Action()
                action.action = 'DISCONNECT'
                action.username = user.username
                action.target = channel
                action.save()

            user.delete()

    def __unicode__(self):
        return "%s %s" % (self.timestamp, self.username)
    
    def save(self, *args, **kwargs):
        if self.pk is None:
            self.identity_id = hmac.new(settings.SECRET_KEY, self.username + str(random.random()) + settings.SALT_KEY, sha256).hexdigest()
            self.identity_key = hmac.new(settings.SECRET_KEY, self.identity_id + str(random.random()) + settings.SALT_KEY, sha256).hexdigest()

        super(User, self).save(*args, **kwargs)
        
    def get_private_channels(self):
        return [x for x in self.channels.all() if hasattr(x, 'privatechannel')]
    